<?php
/**
 * Description of BeanGenerator
 *
 * @author BloumGenerator
 */
class BeanGenerator {

    private $tableMeta;
    private $attributes;
    private $templateBean;
    private $params;

    function __construct($tableMeta, $params) {
        $this->tableMeta = $tableMeta;
        $this->params = $params;
        
        if(!file_exists(Constantes::$TEMPLATES_BEAN_DIR."Bean.bloum"))
            throw new Exception ("Template Bean Not Found!!!");

        $this->templateBean = file_get_contents(Constantes::$TEMPLATES_BEAN_DIR."Bean.bloum");

        $this->organizarAtributos();
        //$this->generate();

    }

    public function organizarAtributos(){

        $this->attributes = $this->tableMeta->getAttributes();

        if(count($this->tableMeta->getFKReferences()) > 0) {
            
            $attrsKeys = array_keys($this->attributes);

            for ($i = 0; $i < count($attrsKeys); $i++) {

                $attributeMeta = $this->attributes[$attrsKeys[$i]];
                $name = $attributeMeta->getName();
                if($attributeMeta->isForeignKey()){

                    $this->attributes[$name] = null;
                    unset ($this->attributes[$name]);

                    $name = str_replace("ID", "", $attributeMeta->getName());
                    
                    $this->attributes[$name] = new AttributeMeta($name, $attributeMeta->getType(), $attributeMeta->isNotNull(), $attributeMeta->isPrimaryKey(), 
                            $attributeMeta->isForeignKey(), $attributeMeta->getDefault(), $attributeMeta->isImportant(), $attributeMeta->isComboDisplay());
                    

                }

            }
            
            foreach ($this->tableMeta->getFKReferenciadas() as $fkMeta) {
                
                if($fkMeta->getSideObject() == Constantes::$SIDE_OBJ_REF){

                    if(strcmp($fkMeta->getCardinality(), Constantes::$CARDINALITY_M) == 0){

                        $name = $fkMeta->getTableFK()->getName()."s";
                        $type = Constantes::$TYPE_ARRAY;

                    }else{
                        $name = $fkMeta->getTableFK()->getName();
                        $type = Constantes::$TYPE_ARRAY;
                    }
                    
                    $this->attributes[$name] = new AttributeMeta($name,$type, false, false, false, "NULL", false, false);
                    
                }
                
            }
        }
        
    }

    public function generate(){

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_NAME_UPPER, ucfirst($this->tableMeta->getName()), $this->templateBean);
        $this->templateBean = str_replace(Constantes::$TPL_BEAN_NAME_LOWER, lcfirst($this->tableMeta->getName()), $this->templateBean);

        $this->generateExtends();
        $this->generateAllVar();
        $this->generateInitVar();
        $this->generateArrayVar();
        $this->generateConstructVar();
        $this->generateGetters();
        $this->generateSetters();

        return $this->templateBean;
    }
    
    public function generateExtends(){

        $numExt = 0;
        $extends = "";

        foreach ($this->tableMeta->getFKReferences() as $fk) {
            if($fk->isExtends()){
                $numExt++;
                $extends = "extends ".ucfirst($fk->getTableReference()->getName())."Bean";
            }

            if($numExt > 1){
                throw new Exception("Erro, Herança Multipla Não Suportado!!!");
            }
        }
        $this->templateBean = str_replace(Constantes::$TPL_BEAN_EXTENDS, $extends, $this->templateBean);
    }

    public function generateAllVar(){

        $attrs = $this->attributes;
        $attrsKeys = array_keys($attrs);
        $var = "";

        for ($i = 0; $i < count($attrsKeys); $i++) {
            if($attrs[$attrsKeys[$i]]->isPrimaryKey() && $attrs[$attrsKeys[$i]]->isForeignKey())
                continue;
            $var .= $this->generateVar($attrs[$attrsKeys[$i]]);
        }

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_VAR, $var, $this->templateBean);

    }
	
    public function generateVar($attributeMeta){

        $var = "private $";
        $annotation = "";

        if($attributeMeta->isForeignKey())
            $annotation = "/**\n\t*@NotNullValidator \n\t*/\n\t";
        else if($attributeMeta->isNotNull())
            $annotation = "/**\n\t*@NotEmptyValidator \n\t*/\n\t";

        $var = $annotation.$var.$attributeMeta->getName();
        $var .= ";\n\t";

        return $var;

    }	

    public function generateInitVar(){

        $attrs = $this->attributes;
        $attrsKeys = array_keys($attrs);
        $initVar = "";

        for ($i = 0; $i < count($attrsKeys); $i++){
            if($attrs[$attrsKeys[$i]]->isPrimaryKey() && $attrs[$attrsKeys[$i]]->isForeignKey())
                continue;
            $initVar .= '$this->'.$attrsKeys[$i].' = $'.$attrsKeys[$i].";\n\t\t";            
        }
        

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_INIT_VAR, $initVar, $this->templateBean);

    }

    public function generateArrayVar(){

        $attrs = $this->tableMeta->getAttributes();
        $attrsKeys = array_keys($attrs);
        $arrayVar = "";

        for ($i = 0; $i < count($attrsKeys); $i++){

            $attMeta = $attrs[$attrsKeys[$i]];
            $name = $attMeta->getName();
            if($attMeta->isForeignKey() && !$attMeta->isPrimaryKey()){
                $aux = str_replace("ID", "", $attrsKeys[$i]);
                $name = $aux."->get".  ucfirst($attrsKeys[$i])."()";
            }
            $arrayVar .= '$arrayBean[\''.$attrsKeys[$i].'\'] = $this->'.$name.";\n\t\t";
        }


        $this->templateBean = str_replace(Constantes::$TPL_BEAN_ARRAY_VAR, $arrayVar, $this->templateBean);

    }

    public function generateConstructVar(){
        $attrs = $this->attributes;
        $attrsKeys = array_keys($attrs);
        $cntVar = "";

        for ($i = 0; $i < count($attrsKeys); $i++){
            $attMeta = $attrs[$attrsKeys[$i]];

            if($attrs[$attrsKeys[$i]]->isPrimaryKey() && $attrs[$attrsKeys[$i]]->isForeignKey())
                continue;
            
            if(strlen(trim($cntVar)) > 0)
                $cntVar .= ', ';
			
            $name = $attMeta->getName();
            $type = $attMeta->getType();
            $default = $attMeta->getDefault();
            $value = Util::getInitValue($type,$default,$attMeta->isForeignKey());

            $cntVar .= "$".$name." = ".$value;
            
        }

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_CONSTRUCT_VAR, $cntVar, $this->templateBean);
    }

    public function generateGetters(){
        $attrs = $this->attributes;
        $attrsKeys = array_keys($attrs);
        $getters = "";

        for ($i = 0; $i < count($attrsKeys); $i++){
            
            if($attrs[$attrsKeys[$i]]->isPrimaryKey() && $attrs[$attrsKeys[$i]]->isForeignKey()){
                
                $fks = $this->tableMeta->getFKReferences();
                $tbRef = null;
                foreach ($fks as $fk) {
                    foreach ($fk->getAttributes() as $fkAtt) {

                        if(strcmp(strtolower($fkAtt->getName()), strtolower($attrsKeys[$i]."ID")) == 0){
                            $tbRef = $fk->getTableReference();
                            break;
                        }
                    }
                    if($tbRef != null) break;
                }
                
                if($tbRef == null) 
                    throw new Exception ("Tabela (".$attrsKeys[$i].") Referenciada Na Herança com (".$this->tableMeta->getName().") Não Encontrada!!!");
                
                
                $getParent = "new ".ucfirst($attrsKeys[$i])."Bean(:varsParent);";
                $varsParent = "";
                
                $attParent = $tbRef->getAttributes();
                $attParentKeys = array_keys($attParent);
                
                for ($j = 0; $j < count($attParentKeys); $j++) {
                    
                    $nameVar = $attParentKeys[$j];
                    
                    if($attParent[$nameVar]->isForeignKey())
                        $nameVar = str_replace ("ID", "", $nameVar);
                    
                    $varsParent .= "parent::get".ucfirst($nameVar)."()";
                    if($j < ( count($attParentKeys)-1 ))
                        $varsParent .= ', ';
                }
                
                $getParent = str_replace(":varsParent", $varsParent, $getParent);
                $getters .= 'public function get'.ucfirst($attrsKeys[$i])."(){ \n\t\treturn $getParent\n\t}\n\n\t";
                
            }
            else{                            
                $getters .= 'public function get'.ucfirst($attrsKeys[$i])."(){ \n\t\treturn \$this->".$attrsKeys[$i].";\n\t}\n\n\t";                
            }
        }

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_GETTERS, $getters, $this->templateBean);
    }

    public function generateSetters(){
        $attrs = $this->attributes;
        $attrsKeys = array_keys($attrs);
        $setters = "";

        for ($i = 0; $i < count($attrsKeys); $i++){
            
            $nameAtt = $attrsKeys[$i];
            
            if($attrs[$nameAtt]->isPrimaryKey() && $attrs[$nameAtt]->isForeignKey()){
                
                $fks = $this->tableMeta->getFKReferences();
                $tbRef = null;
                foreach ($fks as $fk) {
                    foreach ($fk->getAttributes() as $fkAtt) {

                        if(strcmp(strtolower($fkAtt->getName()), strtolower($attrsKeys[$i]."ID")) == 0){
                            $tbRef = $fk->getTableReference();
                            break;
                        }
                    }
                    if($tbRef != null) break;
                }
                
                if($tbRef == null)
                    throw new Exception ("Tabela (".$attrsKeys[$i].") Referenciada Na Herança com (".$this->tableMeta->getName().") Não Encontrada!!!");
                
                $setParent = "parent::__construct(:varsParent);";
                $varsParent = "";
                
                $attParent = $tbRef->getAttributes();
                $attParentKeys = array_keys($attParent);
                
                for ($j = 0; $j < count($attParentKeys); $j++) {
                    
                    $nameVar = $attParentKeys[$j];
                    
                    if($attParent[$nameVar]->isForeignKey())
                        $nameVar = str_replace ("ID", "", $nameVar);
                    
                    $varsParent .= "$".$nameAtt."->get".ucfirst($nameVar)."()";
                    if($j < ( count($attParentKeys)-1 ))
                        $varsParent .= ', ';
                }
                
                $setParent = str_replace(":varsParent", $varsParent, $setParent);
                $setters .= 'public function set'.ucfirst($attrsKeys[$i])."($".$attrsKeys[$i]."){ \n\t\t$setParent\n\t}\n\n\t";            
                
            }
            else{ 
                $setters .= 'public function set'.ucfirst($attrsKeys[$i])."($".$attrsKeys[$i]."){ \n\t\t\$this->".$attrsKeys[$i]." = $".$attrsKeys[$i].";\n\t}\n\n\t";            
            }
        }

        $this->templateBean = str_replace(Constantes::$TPL_BEAN_SETTERS, $setters, $this->templateBean);
    }

    public function generateFile($generate = true){

        if($generate)
            $this->generate();

        $dirModel = "temp_gen/".$this->params[Constantes::$PARAM_PROJECT_NAME]."/model/";

        if(!file_exists($dirModel))
            mkdir ($dirModel, 0755,true);

        $fp = fopen($dirModel.ucfirst($this->tableMeta->getName())."Bean.class.php", "w+");
        fwrite($fp, $this->templateBean);
        fclose($fp);
    }

}
?>
